import { IPSApplication, IPSAppPortlet, IPSAppPortletCat } from '@ibiz/dynamic-model-api';
import { IAppDashboardDesignService, IParam, IUtilService } from 'ibz-core';

/**
 * @description 数据看板设计服务
 * @class AppDashboardDesignService
 */
export class AppDashboardDesignService implements IAppDashboardDesignService {
  /**
   * @description 数据看板设计服务对象
   * @private
   * @static
   * @type {AppDashboardDesignService}
   * @memberof AppDashboardDesignService
   */
  private static intance: AppDashboardDesignService;

  /**
   * @description 获取数据看板设计服务（单例对象）
   * @memberof AppDashboardDesignService
   */
  public static getInstance() {
    if (!this.intance) {
      this.intance = new AppDashboardDesignService();
    }
    return this.intance;
  }

  /**
   * @description 保存模型数据
   * @param {string} serviceKey 工具服务标识
   * @param {IParam} context 应用上下文
   * @param {IParam} viewParam 保存视图参数
   * @memberof AppDashboardDesignService
   */
  public saveModelData(serviceKey: string, context: IParam, viewParam: IParam): Promise<IParam> {
    return new Promise((resolve: any, reject: any) => {
      App.getUtilService()
        .getService(context, serviceKey)
        .then((utilService: IUtilService) => {
          const saveModel: IParam[] = [];
          if (viewParam.model) {
            for (const model of viewParam.model) {
              const temp = { ...model };
              delete temp.modelData;
              saveModel.push(temp);
            }
          }
          viewParam.model = saveModel;
          utilService
            .saveModelData(context, viewParam)
            .then((result: IParam) => {
              resolve(result);
            })
            .catch((error: IParam) => {
              reject(error);
            });
        });
    });
  }

  /**
   * @description 加载门户部件集合
   * @param {IParam} context 应用上下文
   * @param {IParam} viewParam 视图参数
   */
  public async loadPortletList(context: IParam, viewParam: IParam): Promise<IParam> {
    const app: IPSApplication = App.getModel();
    const list: any[] = [];
    const portletCats = app.getAllPSAppPortletCats() || [];
    const portlets = app.getAllPSAppPortlets() || [];
    portlets.forEach((portlet: IPSAppPortlet) => {
      const appDe = portlet.getPSAppDataEntity?.();
      const portletCat = portletCats.find(
        (cat: IPSAppPortletCat) => cat.codeName == portlet.getPSAppPortletCat?.()?.codeName,
      );
      const temp = {
        type: 'app',
        portletType: (portlet as any).portletType,
        portletCodeName: portlet.codeName,
        portletName: portlet.name,
        portletImage: (portlet.getPSControl?.() as any)?.getPSSysImage?.()?.cssClass,
        groupCodeName: portletCat?.codeName || '',
        groupName: portletCat?.name || '',
        appCodeName: appDe?.codeName || app.pKGCodeName,
        appName: appDe?.logicName || app.name,
        detailText: portlet.userTag,
        modelData: portlet.getPSControl?.(),
      };
      list.push(temp);
    });
    const datas: any[] = this.filterData(list, viewParam.appdeNamePath);
    const result = this.prepareList(datas);
    const groups = this.prepareGroup(datas);
    return { data: datas, result: result.reverse(), groups: groups };
  }

  /**
   * @description 过滤数据
   * @param {any[]} datas
   * @memberof AppDashboardDesignService
   */
  private filterData(datas: any[] = [], dataType: string): any[] {
    const items: any[] = [];
    datas.forEach((data: any) => {
      if (Object.is(data.type, 'app')) {
        items.push(data);
      }
      if (Object.is(data.appCodeName, dataType)) {
        items.push(data);
      }
    });
    return items;
  }

  /**
   * @description 分组集合
   * @param {any[]} [datas=[]]
   * @returns {any[]}
   * @memberof AppDashboardDesignService
   */
  private prepareGroup(datas: any[] = []): any[] {
    const items: any[] = [];
    datas.forEach((data: any) => {
      const item = items.find((item: any) => Object.is(item.value, data.groupCodeName));
      if (item) {
        const _item = item.children.find((a: any) => Object.is(a.portletCodeName, data.portletCodeName));
        if (!_item) {
          item.children.push(data);
        }
      } else {
        items.push({ name: data.groupName, value: data.groupCodeName, children: [data] });
      }
    });
    return items;
  }

  /**
   * @description 准备list集合
   * @memberof AppDashboardDesignService
   */
  private prepareList(datas: any[] = []): any[] {
    const list: any[] = [];
    datas.forEach((data: any) => {
      let item = list.find((item: any) => Object.is(data.type, item.type));
      if (!item) {
        item = {};
        Object.assign(item, {
          type: data.type,
          name: Object.is(data.type, 'app') ? '全局' : data.appName,
          children: [],
        });
        list.push(item);
      }
      this.prepareList2(item.children, data);
    });
    return list;
  }

  /**
   * @description 准备list项集合
   * @param {any[]} [children=[]]
   * @param {*} [data={}]
   * @memberof AppDashboardDesignService
   */
  private prepareList2(children: any[] = [], data: any = {}) {
    let item = children.find((item: any) => Object.is(data.groupCodeName, item.type));
    if (!item) {
      item = {};
      Object.assign(item, {
        type: data.groupCodeName,
        name: data.groupName,
        children: [],
      });
      children.push(item);
    }
    const _item = item.children.find((a: any) => Object.is(a.portletCodeName, data.portletCodeName));
    if (!_item) {
      item.children.push(data);
    }
  }
}
